package com.wmyg.antifake.controller;

import com.wmyg.antifake.dto.PhoneCheckDto;
import com.wmyg.antifake.dto.SignUserDto;
import com.wmyg.antifake.dto.SmsCodeDto;
import com.wmyg.antifake.entity.BkUser;
import com.wmyg.antifake.service.BkUserService;
import com.wmyg.antifake.utils.SmsUtils;
import com.wmyg.antifake.vo.SignResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author 王卓逸
 * @program TODO
 * @description TODO
 * @create 2019-05-18
 */
@Slf4j
@RestController
@RequestMapping(value = "/sign")
public class SignController {

    @Autowired
    BkUserService bkUserService;

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 提交部分信息获取短信验证码
     * @param smsCodeDto 请求参数对象
     * @param bindingResult 参数初步校验结果
     * @return 响应信息
     */
    @PostMapping(value = "/smscode")
    public SignResult getSmsCode(@Valid SmsCodeDto smsCodeDto, BindingResult bindingResult) {
        SignResult result = signParamCheck(bindingResult, "getSmsCode");
        if (null != result) {
            return result;
        }
        if (smsCodeDto.getType() == 0) {
            BkUser bkUser = bkUserService.findByPhone(smsCodeDto.getPhone());
            if (null != bkUser) {
                return new SignResult(1, "此手机号已注册");
            }
        }
        result = new SignResult(0, "短信验证码获取成功");
        String code = SmsUtils.getSmsYzm();
        SmsUtils.sendSms(smsCodeDto.getPhone(), code, "");
        redisTemplate.opsForValue().set("phonecode" + smsCodeDto.getPhone(), code, 60 * 10, TimeUnit.SECONDS);
        log.info("The phone {} got a code {}", smsCodeDto.getPhone(), code);
        return result;
    }

    /**
     * 短信验证码验证
     * @param phoneCheckDto 请求参数对象
     * @param bindingResult 参数初步校验结果
     * @return 响应信息
     */
    @GetMapping(value = "/phonecheck")
    public SignResult phoneCheck(@Valid PhoneCheckDto phoneCheckDto, BindingResult bindingResult) {
        SignResult result = signParamCheck(bindingResult, "phoneCheck");
        if (null != result) {
            return result;
        }
        String code = (String) redisTemplate.opsForValue().get("phonecode" + phoneCheckDto.getPhone());
        log.info("Got the code {} through the phone {}", code, phoneCheckDto.getPhone());
        if (!phoneCheckDto.getSmsCode().equals(code)) {
            return new SignResult(1, "短信验证码不正确");
        }
        return new SignResult(0, "手机号验证成功");
    }

    /**
     * 完成注册
     * @param signUserDto 用户注册请求参数对象
     * @param bindingResult 参数初步校验结果
     * @return 响应信息
     */
    @PostMapping(value = "/signuser")
    public SignResult signUp(SignUserDto signUserDto, BindingResult bindingResult) {
        SignResult result = signParamCheck(bindingResult, "signUp");
        if (null != result) {
            return result;
        }
        BkUser bkUser = new BkUser();
        bkUser.setUsername(signUserDto.getUserName());
        bkUser.setPassword(signUserDto.getUserPass());
        bkUser.setPhone(signUserDto.getPhone());
        Boolean flag = bkUserService.signUp(bkUser);
        if (!flag) {
            return new SignResult(1, "该用户名已被使用");
        }
        return new SignResult(0, "注册成功");
    }

    /**
     * 将参数初步校验结果转化为响应信息
     * @param bindingResult 参数初步校验结果
     * @param method 方法名
     * @return 响应信息，空则是初步校验无错误
     */
    private SignResult signParamCheck(BindingResult bindingResult, String method) {
        if (bindingResult.hasErrors()) {
            for (ObjectError error :
                    bindingResult.getAllErrors()) {
                FieldError fieldError = (FieldError) error;
                log.error("The {} param has error in {}, cause {}", method, fieldError.getField(), fieldError.getDefaultMessage());
                return new SignResult(1, fieldError.getDefaultMessage());
            }
        }
        return null;
    }

    @GetMapping("/hello")
    public String sayHello(Date date) {
        return "hello";
    }

    @PutMapping(value = "/changepassword")
    public SignResult forgerPassword(SignUserDto signUserDto, BindingResult bindingResult) {
        SignResult result = signParamCheck(bindingResult, "signUp");
        if (null != result) {
            return result;
        }
        if (bkUserService.changePassword(signUserDto.getUserPass(), signUserDto.getUserName(), signUserDto.getPhone())) {
            return new SignResult(0, "修改成功");
        } else {
            return new SignResult(1, "用户名或手机号不正确");
        }
    }

}
